(function(w){

    w.fn.wJabber = function(options) {
        //var calls = multiCallContainer('call', 'calllist');
        var ws = w.extend({
            _callcontainer:"#callcontainer",
            _calllist:"#calllist",
            _parentId:"calllist", //  Must same value to  _calllist
            
        }, options );
        
//        var settings = { // @win, Actually this is not important
//            ready: phoneReadyCallback, /* Callback when phone is ready for use */
//            error: phoneErrorCallback, /* Error callback */
//            encodeBase64: ciscobase.util.crypto.b64Encode,
//            verbose: true,
//            log: function (msg, context) {
//                //console.trace();
//                if (typeof console !== "undefined" && console.log) {         
//                    console.log(msg);
//                    if (context) {
//                        if(console.dir) {
//                            console.log(context);
//                        } else if(typeof JSON !== "undefined" && JSON.stringify) {
//                            console.log(JSON.stringify(context,null,2));
//                        } else {
//                            console.log(context);
//                        }
//                    }
//                };
//            },
//            contactLookupJsonpHost: ""
//        };
        
        var callPrefix = "call";
        var calllists = {},
            selectedCallId=null;
        
         
        console.log("wJabber Start");


        var methods = {
            setCalls: function(calls){
              //calls =
            },
            loginAko:function(ako){
                w(ako).cwic('registerPhone', {
                    user: 'winzter143',
                    password: 'fatbox123',
                    cucm: '192.168.101.8',
                    mode: 'SoftPhone',
                    authenticate: "false", //auth,
                    forceRegistration: "true", //forcereg,

                    devicesAvailable: function(devices,phoneMode,callback,automatic) {
                        console.log("Connect to ECPDemo");
                        callback("SoftPhone", "ECPDemo","");
                    },
                    success: function(registration) {
                        //settings.log('Registration succeeded. Registration: ',registration);
                        // videodirection => tells wethere video capable
                        w("#call").click(function(){
                            console.log("call Click");
                            var _num = w(this).attr('number');
                            methods.tawag(_num?_num:"9998");
                        });
                    },
                    error: function(){
                        methods.handleLoginFailure();
                    }
                }); // End of registerPhone
            },
            logoutAko: function (){
                w('#phonecontainer').cwic('unregisterPhone', {
                    forceLogout: true,
                    // the complete callback is always called after unregistering
                    complete: function(){
                        methods.handleLoggedOut();
                    }
                });
            },
            /*
             * Remove All registered call. Incomming/ 
             */
            handleLoggedOut: function (){
                for(var call in calllists) {
                    if(calllists.hasOwnProperty(call)) {
                        methods.removeCall(calllists[call].id);
                    }
                }
                //calls.removeAll();
            },
        
            tawag:function(num){
                console.log("Call the user: "+num);
                var videodirection = true;
                var originateObject = {
                    //participant: {recipient: "6969"}, // My Adrouds
                    participant: {recipient: "9998"}, // Syntax-pc
                    videoDirection: (videodirection ? 'SendRecv':(w(document).cwic('about').capabilities.video ? 'RecvOnly' : 'Inactive')),
                    remoteVideoWindow: 'videocallobject'};
                    w('#phonecontainer').cwic('startConversation',originateObject);

            },
            endTawag:function (){
                console.log("endtawag calls");
                calls.getCallDiv().cwic('endConversation');
            },
        
            handleLoginFailure: function(){
            alert("Error");
            },


            
            handleConversationStart:function (event, conversation, containerdiv) {
                console.log("start handleConversationStart("+event+", "+conversation+", "+containerdiv+")");
                methods.addCall(conversation, containerdiv);
                methods.updateConversationInfo(conversation, ws._callcontainer);
            },

            /**
             * 
             * @param {type} conversation
             * @param {type} callcontainer -> the DIV for video container
             * @returns {unresolved}
             */
            updateConversationInfo:function (conversation, callcontainer){
                
                if(!methods.getSelectedCall() 
                    || methods.getSelectedCall().callId !== conversation.callId) {
                    // special case where hold shows up for previous call after the current call is answered if the
                    // previous call was in process when the user clicked answer to a new incoming call.
                    // Remove the video window so it blanks out correctly
                    if (conversation && conversation.callState 
                            && ((conversation.callState==='Hold')||(conversation.callState==='RemHold'))) {
                        settings.log("Hold received for non-current call, checking for video");
                        if (videoObject) {
                            settings.log("Hold received for non-current call, removing video conversation.callId: " + conversation.callId);
                            methods.getCallDiv(conversation.callId).cwic('updateConversation',{'removeRemoteVideoWindow':videoObject});
                        }
                    }
                    else {
                        settings.log("updateConversationInfo() event not for current call, ignoring");
                    }

                    return;
                }
                var $callcontainer = w(callcontainer);
                methods.updateTransferConferenceLists(conversation);
                $callcontainer.css('display','inline-block');
                if(conversation.isConference) {
                    //$callcontainer.find('.remotename').text("Conference");
                }
                else if(conversation.callType === "Outgoing") {
                    console.log("Outgoing Call");
                    //$callcontainer.find('.remotename').text(conversation.calledPartyDirectoryNumber + ((conversation.participant.name === "") ? "" : " - " + conversation.participant.name));
                }
                else if (conversation.callType === "Incoming") {
                    //$callcontainer.find('.remotename').text(conversation.callingPartyDirectoryNumber + ((conversation.participant.name === "") ? "" : " - " + conversation.participant.name));
                }
                //$callcontainer.find('.callinfo').text(conversation.callState);

                if (conversation.callState === 'Hold' || conversation.callState === 'RemHold') {
                    // In some cases, if the video window is not removed on hold, it cannot be re-added
                    // on resume.
                    // remove the video window from a call on hold to blank out the video window
                    // and to allow the video to be re-added properly when the call is resumed later

                    settings.log("Hold received, removing video");
                    //$callcontainer.find('.holdresumebtn').attr('disabled', !conversation.capabilities.canResume).text('Resume').addClass('held');
                    if (videoObject) {
                        console.log("Voideo Object and calling {updateConversation}");
                        calllists.getCallDiv().cwic('updateConversation',{'removeRemoteVideoWindow':videoObject});
                    }
                } else {
                    //$callcontainer.find('.holdresumebtn').attr('disabled', !conversation.capabilities.canHold).text('Hold').removeClass('held');
                }
                //$callcontainer.find('.endbtn').attr('disabled', !conversation.capabilities.canEndCall);

                if (conversation.state === 'Reorder') {
                    alert("Call failed");
                    //$callcontainer.find('.callinfo').text('Call failed');
                }

                if (conversation && conversation.callState === "Connected" && (conversation.videoDirection === "RecvOnly" || conversation.videoDirection === "SendRecv")) {
                    console.log("Conversion Connected!!!!!!");

                    if (conversation.callEvent === 'evCallStarted' || conversation.callEvent === 'evVideoAvailable'){
                        console.log("Conversion Video Available");
                        calllists.getCallDiv().cwic('showCallInExternalWindow');
                        //calllists.setExternalVideolTitle();
                    }

                    if(videoObject) {
                        console.log("VideoObject call {updateConversation}");
                        calllists.getCallDiv().cwic('updateConversation',{'addRemoteVideoWindow':videoObject});
                    }
                    else {
                        // The update for the conversation that video is ready can occur before the createVideoWindow() call  
                        // returns asynchronously on some browsers, especially on Safari and background tabs.  Save off the 
                        // conversation so that we can add the window to it when it is ready.
                        delayedVideoConversation = conversation;
                        console.log("Delayed Video Conversation???");
                    }
                    // @win -> Since no popup Comment out this one then
                    //if(popupwindow && !popupwindow.closed && popupwindow.videoObject) {
                    //    console.log("");
                    //    calllists.getCallDiv().cwic('updateConversation',{'addRemoteVideoWindow':popupwindow.videoObject,window:popupwindow});
                    //}
                }
                if(conversation.audioMuted) {
                    //$callcontainer.find('.muteaudiobtn').attr('disabled', !conversation.capabilities.canUnmuteAudio);
                    //$callcontainer.find('.muteaudiobtn').text('Unmute Audio').addClass('muted');
                } else {
                    //$callcontainer.find('.muteaudiobtn').attr('disabled', !conversation.capabilities.canMuteAudio);
                    //$callcontainer.find('.muteaudiobtn').text('Mute Audio').removeClass('muted');
                }

                if(conversation.videoMuted) {
                    //$callcontainer.find('.mutevideobtn').attr('disabled', !conversation.capabilities.canUnmuteVideo);
                    //$callcontainer.find('.mutevideobtn').text('Unmute Video').addClass('muted');
                } else {
                    //$callcontainer.find('.mutevideobtn').attr('disabled', !conversation.capabilities.canMuteVideo);
                    //$callcontainer.find('.mutevideobtn').text('Mute Video').removeClass('muted');
                    //calllists.setExternalVideolTitle();
                }

                if(conversation.videoDirection === "Inactive" || conversation.videoDirection === "RecvOnly") {
                    //$callcontainer.find('.escalatebtn').text('Escalate').attr('disabled',!conversation.capabilities.canUpdateVideoCapability);
                } else {
                    //$callcontainer.find('.escalatebtn').text('De-escalate').attr('disabled',!conversation.capabilities.canUpdateVideoCapability);
                }


            },// function updateConversationInfo(conversation, callcontainer){
            getSelectedCall: function() {
                return calllists[selectedCallId];
            },

            addCall: function(conversation, container) {
                var callIsNew = false;
                console.log("Start addCall");
                console.log("testing calllists[conversation.callId]"+conversation.callId);
                if(!(calllists[conversation.callId])) {
                    // no call or old call is not connected or not (Ringout || OffHook && canEndCall) and new one is something more active
                    // entirely too complicated of a condition, but that's asynchronous multiple calls for you
                    if(!selectedCallId || !calllists[selectedCallId] || (calllists[selectedCallId].callState !== "Ringout" && calls[selectedCallId].callState !== 'Connected' && (calls[selectedCallId].callState !== 'OffHook' || !calls[selectedCallId].capabilities.canEndCall) && (conversation.callState === 'Ringin' || conversation.callState === 'Ringout'||conversation.callState === 'OffHook'))) {
                        selectedCallId = conversation.callId;
                        //$('ul#calllist li').removeClass('selected');
                    }
                    console.log("===========>>> parentId"+ws._parentId);
                    var $calls = $('#' + ws._parentId);
                    $calls.append($('<li' +(selectedCallId === conversation.callId ? ' class="selected"' : '') + ' id="' + callPrefix + '_' + conversation.callId + '"><span class="controls"><button type="button" class="answerbtn">Answer</button> <button type="button" class="divertbtn">iDivert</button></span><span class="name"></span><span class="state"></span>'));//<b>' + conversation.participant.name + ':</b> ' + conversation.participant.recipient + '</li>'));
                    //$calls[0].scrollTop = $calls[0].scrollHeight;
                    console.log("New call register: "+callPrefix+'_'+conversation.callId);
                    $newCall = $('#'+callPrefix+'_'+conversation.callId);
    //                $newCall.find('.answerbtn').click(incomingAnswerClick);
    //                $newCall.find('.divertbtn').click(incomingDivertClick);
                    $newCall.bind('conversationUpdate.cwic',methods.handleConversationUpdate)
                            .bind('conversationEnd.cwic', methods.handleConversationEnd);
                    callIsNew = true;
                    $('#switchmodebtn').attr('disabled',true);
                }
                calllists[conversation.callId] = conversation;
                methods.updateCall(conversation, container);
                return callIsNew;
            },
            
            updateCall: function(conversation,container) {
                console.log("start updateCall("+callPrefix+"_"+conversation.callId+")");
                var $update = $('#' + callPrefix + '_' + conversation.callId);
                var name = '';
                var number='';
                var title = '';
                var state = '';
                if(container) {
                    var $container = $(container);
                    var classes = methods.getCwicClasses($container);
                    var oldclasses = methods.getCwicClasses($update);
                    console.log("new("+classes+") OLD("+oldclasses+")");
                    $container.removeClass(classes);
                    $update.data('cwic',$container.data('cwic')).removeClass(oldclasses).addClass(classes);
                }
                if(conversation.callState === 'Reorder') {
                    name = conversation.calledPartyNumber;
                    state = 'Call Failed';
                } else {
                    state = conversation.callState;
                    // @win -> No conference feature
                    //if (conversation.isConference) {
                    //    name = 'Conference';
                    //    for(var i=0;i<conversation.participants.length;i++) {
                    //        title += (i>0 ? ', ' : '') + conversation.participants.name;
                    //    }
                    //}
                    if (conversation.callType === "Outgoing") {
                        name = conversation.calledPartyName;
                        number = conversation.calledPartyNumber;
                        title = conversation.calledPartyDirectoryNumber;
                    }
                    // Furely out going only
                    //else if (conversation.callType === "Incoming") {
                    //    name = conversation.callingPartyName;
                    //    number = conversation.callingPartyNumber;
                    //    title = conversation.callingPartyDirectoryNumber;
                    //}
                }
                //if(conversation.capabilities.canImmediateDivert || conversation.capabilities.canAnswerCall) {
                //    $update.find('.divertbtn').attr('disabled', !conversation.capabilities.canImmediateDivert);
                //    $update.find('.answerbtn').attr('disabled', !conversation.capabilities.canAnswerCall);
                //    $update.find('.controls').show();
                //} else {
                //    $update.find('.controls').hide();
                //}
                //$update.find('.name').text(((number === '') ? '' : number + ' - ') + name).attr('title',title);
                //$update.find('.state').text(state).attr('class', 'state ' + conversation.callState);
                if(!selectedCallId) {
                    methods.setSelectedCall(conversation.callId);
                }
            },
            getCwicClasses: function(el) {
                var classes = w(el).attr('class');
                var classestoadd = [];
                if(classes) {
                    classes = classes.split(' ');
                    for(var i=0;i<classes.length;i++) {
                        if(classes[i].substring(4,0) === 'cwic') {
                            console.log("Push Call to "+classes[i]);
                            classestoadd.push(classes[i]);
                        }
                    }
                }
                return classestoadd.join(' ');
            },
            getCallDiv: function(callId) { // from Helper
                console.log("Start getCallDiv");
                if(!callId) {
                    callId = selectedCallId;
                }
                var callDiv = callPrefix+'_'+callId;
                console.log("getCallDiv: "+callDiv);
                return w('#'+callDiv);
            },

            setSelectedCall: function(callid) { // from Helper
                selectedCallId = callid;
                //w('#calllist li').removeClass('selected');
                //w('#'+callPrefix+'_'+callid).addClass('selected');
                methods.updateConversationInfo(calllists[selectedCallId], ws._callcontainer);
            },

            isCallListEmpty:function(){ // from Helper
                
                //if (w(ws._calllist).children().size()) {
                //    return false;
                //}
                return true;
            },
            
            handleConversationEnd: function(event, conversation) {
                //$('#callcontainer').hide();
                calllists.removeCall(conversation.callId);

                settings.log('conversationEnd Event for conversation:'+conversation.callId);
                delayedVideoConversation = null;
                if (calllists.isCallListEmpty()){
                    //calls.removeExternalVideoTitle();
                    //$(document).cwic('hideExternalWindow');
                    //$('#closeexternalwindow').attr('disabled', false);
                    //$('#externalpreview').attr('disabled', false);
                } else {
                    //calls.setExternalVideolTitle();
                }
            },

            handleConversationIncoming:function (event, conversation, containerdiv) {
                console.log("start handleConversationIncoming");
                //calls.addCall(conversation, containerdiv);
            },
            updateTransferConferenceLists: function(conversation) {
                console.log("Start updateTransferConferenceLists - sounds not use to this project");
                var existingCalls = methods.getCalls();
                var text = '';
                //w('#conferencelist').empty();
                //w('#transferlist').empty();
                var conferenceAvailable = false;
                var transferAvailable = false;
                if(conversation && conversation.callState === "Connected") {
                    for(var call in existingCalls) {
                        if(existingCalls.hasOwnProperty(call)) {
                            if(conversation.capabilities.canJoinAcrossLine && existingCalls[call].callId !== conversation.callId && existingCalls[call].capabilities.canJoinAcrossLine) {
                                if(existingCalls[call].isConference) {
                                    text = "Conference";
                                } else if(existingCalls[call].callType === "Outgoing") {
                                    text=existingCalls[call].calledPartyDirectoryNumber;
                                } else {
                                    text=existingCalls[call].callingPartyDirectoryNumber;
                                }
                                //$('#conferencelist').append("<option value='" + existingCalls[call].callId + "'>" + text + "</option>");
                                conferenceAvailable = true;
                            }
                            if(conversation.capabilities.canDirectTransfer && existingCalls[call].callId !== conversation.callId && existingCalls[call].capabilities.canDirectTransfer) {
                                if(existingCalls[call].isConference) {
                                    text = "Conference";
                                } else if(existingCalls[call].callType === "Outgoing") {
                                    text=existingCalls[call].calledPartyDirectoryNumber;
                                } else {
                                    text=existingCalls[call].callingPartyDirectoryNumber;
                                }
                                //$('#transferlist').append("<option value='" + existingCalls[call].callId + "'>" + text + "</option>");
                                transferAvailable = true;
                            }
                        }
                    }
                }
                //$('#conferencebtn').attr('disabled', !conferenceAvailable);
                //$('#transferbtn').attr('disabled', !transferAvailable);
            },
            removeCall: function(callid) {
                if(calls[callid]) {
                    delete calls[callid];
                    var $remove = $('#' + callPrefix + '_' + callid);
                    // Unbind and related button
                    //$remove.find('.answerbtn').unbind();
                    //$remove.find('.divertbtn').unbind();
                    //$remove.unbind().remove();
                }
                selectedCallId = null;
                for(var call in calls) {
                    if(calls.hasOwnProperty(call)) {
                        selectedCallId = calls[call].id;
                    }
                }
                methods.setSelectedCall(selectedCallId);
                if(!selectedCallId) {
                    //$('#switchmodebtn').removeAttr('disabled');
                    //$('#callcontainer').hide();
                    //if(popupwindow) {popupwindow.close();}
                }
            },
        };

        w('#phonecontainer')
            .bind('conversationStart.cwic', methods.handleConversationStart)
            .bind('conversationIncoming.cwic', methods.handleConversationIncoming)
            ;

        w("#phonecontainer").cwic('init', { 
            ready: function() {
                // Create Video Window
                w('#remotevideocontainer').cwic('createVideoWindow',{
                    id: 'videoobject',
                    success: function(pluginid) {
                        //Video object has correctly loaded
                    }
                });   

                w(this).cwic('disableCertValidation');
                methods.loginAko(this);
            }// ready:
        }); // Init

    };// wJabber function
        
        
    w(document).ready(function(){
        var tawags = w("#menu").wJabber();
        console.log("wDocument Ready");
    });

    w("#tap_postpaid").click(function(){
        console.log("Click----------")
    });
    
    w("#logout").click(function(){
        console.log("LogOut Click");
        // Logout
        w('#phonecontainer').cwic('unregisterPhone', {
            forceLogout: true,
            // the complete callback is always called after unregistering
            complete: function(){
                //handleLoggedOut(); //
                console.log("Unregister");
            }
        });

    });
    w("#login").click(function(){
        console.log("Click Login");
        loginAko("#phonecontainer");
    });

//    w("#call").click(function(){
//        console.log("Call Click");
//        //  End call
//        //tawags.tawag("9998");
//        tawags.tawag("6969");
//    });
    w(".calls").click(function(){
        console.log("Call Click");
        //  End call
        tawags.tawag(w(this).attr("number"));
    });    

    w("#endcall").click(function(){
        //  End call
        console.log("End Call Click");
        tawags.endTawag();
    });

} (jQuery));